﻿// The Nova Project by Ken Beckett.
// Copyright (C) 2007-2012 Inevitable Software, all rights reserved.
// Released under the Common Development and Distribution License, CDDL-1.0: http://opensource.org/licenses/cddl1.php

using System.Collections.Generic;
using System.Windows.Media;

using Nova.CodeDOM;

namespace Nova.UI
{
    /// <summary>
    /// The view model for a <see cref="CodeDOM.VariableDecl"/>.
    /// </summary>
    public abstract class VariableDeclVM : StatementVM
    {
        #region /* FIELDS */

        protected ExpressionVM _typeVM;
        protected ExpressionVM _initializationVM;

        #endregion

        #region /* CONSTRUCTORS */

        /// <summary>
        /// Create a view model instance for the specified <see cref="CodeDOM.VariableDecl"/>.
        /// </summary>
        protected VariableDeclVM(VariableDecl variableDecl, Dictionary<CodeObject, CodeObjectVM> dictionary)
            : base(variableDecl, dictionary)
        {
            if (variableDecl.Type != null)
                _typeVM = (ExpressionVM)CreateVM(variableDecl.Type, false, dictionary);
            if (variableDecl.Initialization != null)
                _initializationVM = (ExpressionVM)CreateVM(variableDecl.Initialization, false, dictionary);
        }

        #endregion

        #region /* PROPERTIES */

        /// <summary>
        /// The underlying <see cref="CodeDOM.VariableDecl"/> model.
        /// </summary>
        public VariableDecl VariableDecl
        {
            get { return (VariableDecl)CodeObject; }
        }

        /// <summary>
        /// The type of the variable declaration.
        /// </summary>
        public virtual ExpressionVM Type
        {
            get { return _typeVM; }
        }

        /// <summary>
        /// An optional initialization <see cref="ExpressionVM"/>.
        /// </summary>
        public ExpressionVM Initialization
        {
            get { return _initializationVM; }
        }

        /// <summary>
        /// True if the variable has an initialization <see cref="ExpressionVM"/>.
        /// </summary>
        public bool HasInitialization
        {
            get { return (_initializationVM != null); }
        }

        #endregion

        #region /* METHODS */

        #endregion

        #region /* RENDERING */

        public static readonly Brush StaticBorderBrush = DarkPalerGreen;
        public static readonly Brush StaticBackgroundBrush = PalerGreen;

        public override Brush BorderBrush
        {
            get { return StaticBorderBrush; }
        }

        public override Brush BackgroundBrush
        {
            get { return StaticBackgroundBrush; }
        }

        public virtual void RenderType(CodeRenderer renderer, RenderFlags flags)
        {
            ExpressionVM type = Type;
            if (type != null)
            {
                RenderFlags passFlags = (flags & RenderFlags.PassMask);
                type.Render(renderer, passFlags | RenderFlags.IsPrefix | RenderFlags.Declaration);
            }
        }

        protected override void RenderStatement(CodeRenderer renderer, RenderFlags flags)
        {
            RenderType(renderer, flags);
            renderer.RenderText(VariableDecl.Name, IDENTIFIER_BRUSH, this);
        }

        protected void RenderInitialization(CodeRenderer renderer, RenderFlags flags)
        {
            renderer.RenderText(" ", PUNC_BRUSH, this);
            if (OperatorVM.UseAlternativeDisplay)
                AssignmentVM.AltRenderOperator(renderer, OPERATOR_BRUSH, this);
            else
                AssignmentVM.RenderOperator(renderer, OPERATOR_BRUSH, this);

           Initialization.Render(renderer, flags | RenderFlags.ForceBorder | RenderFlags.PrefixSpace);
        }

        public override void RenderVisible(CodeRenderer renderer, RenderFlags flags)
        {
            base.RenderVisible(renderer, flags);
            if (_initializationVM != null)
                _initializationVM.RenderVisible(renderer, flags);
        }

        public override void UnRender()
        {
            if (_typeVM != null)
                _typeVM.UnRender();
            if (_initializationVM != null)
                _initializationVM.UnRender();
            base.UnRender();
        }

        #endregion
    }
}
